<template>
  <div class="trade-page">
    <div class="main-area">
      <!-- 主内容区，左侧 -->
      <div class="main-content">
        <div class="shangmian">
          <div class="row row-top">
            <div class="block block-chart">
              <div class="block-title">分时线（{{ name }}_{{ symbol }}）</div>
              <div class="chart-area">
                <div ref="timeshareChart" class="chart-placeholder"></div>
              </div>
            </div>
            <!-- 委托表单+五档行情 -->
            <div class="block block-entrust">
              <div class="entrust-depth-card">
                <div class="entrust-two-cols">
                  <!-- 左侧：股票代码、委托、价格、买入量等 -->
                  <div class="entrust-form">
                    <el-input v-model="stockQuery" placeholder="股票代码/名称搜索" size="mini" prefix-icon="el-icon-search"
                      class="entrust-form-item" @focus="stockDialogVisible = true" clearable />
                    <el-button type="info" plain size="mini" class="entrust-form-item" disabled>限价委托</el-button>
                    <div class="entrust-flex-row entrust-form-item">
                      <el-button type="text" @click="priceMinus" icon="el-icon-minus" />
                      <el-input v-model="price" size="mini" class="entrust-flex-input" style="text-align:center;" />
                      <el-button type="text" @click="pricePlus" icon="el-icon-plus" />
                    </div>
                    <div class="flex-row mb8">
                      <span class="limit-price" style="color:#28b76b;">跌停 {{ downLimit }}</span>
                      <span class="limit-price" style="color:#ff4d4f; margin-left:14px;">涨停 {{ upLimit }}</span>
                    </div>
                    <div class="entrust-flex-row entrust-form-item">
                      <el-button type="text" @click="countMinus" icon="el-icon-minus" />
                      <el-input v-model="count" size="mini" placeholder="买入量/卖出量" class="entrust-flex-input"
                        style="text-align:center;" />
                      <el-button type="text" @click="countPlus" icon="el-icon-plus" />
                    </div>
                  </div>
                  <!-- 右侧：五档行情 -->
                  <div class="depth-side">
                    <div class="depth-table">
                      <div v-for="item in sellList" :key="item.value" class="depth-row sell-row">
                        <span class="depth-type">{{ item.value }}</span>
                        <span class="depth-price">{{ item.askprice }}</span>
                        <span class="depth-volume">{{ item.askvolume }}</span>
                      </div>
                      <div class="depth-middle-line"></div>
                      <div v-for="item in buyList" :key="item.value" class="depth-row buy-row">
                        <span class="depth-type">{{ item.value }}</span>
                        <span class="depth-price">{{ item.bidprice }}</span>
                        <span class="depth-volume">{{ item.bidvolume }}</span>
                      </div>
                    </div>
                  </div>
                </div>
                <!-- 买入卖出按钮和下方比例+加到列表 -->
                <div class="entrust-btns-bottom-vertical">
                  <el-button type="warning" class="entrust-buy" @click="handleBatchBuy()">买入</el-button>
                  <el-button type="success" class="entrust-sell" @click="handleBatchSell()">卖出</el-button>
                  <div class="entrust-ratio-add-group">
                    <el-input v-model="ratio" size="mini" placeholder="比例 输入1~100" class="entrust-ratio-input" />
                    <el-button type="warning" @click="addSymbolToList">加到列表</el-button>
                  </div>
                </div>
              </div>
            </div>
            <div class="block block-group">
              <div class="block-title group-title">
                交易群组
                <el-button type="primary" icon="el-icon-plus" size="mini" circle style="float:right;"
                  @click="showAddGroupDialog = true" />
              </div>
              <el-menu @select="handleGroupSelect" style="border:none; margin-top:2px; font-size:14px;">
                <el-menu-item v-for="group in groupList" :key="group.id" :index="group.id.toString()"
                  style="display: flex; align-items: center; justify-content: space-between;">
                  <span @click="activeGroup = group" style="flex:1;cursor:pointer;">{{ group.name }}</span>
                  <el-button type="text" icon="el-icon-delete" size="mini" @click.stop.prevent="deleteGroup(group.id)"
                    style="color:#f56c6c; margin-left:4px;" v-if="groupList.length > 0" />
                </el-menu-item>
              </el-menu>
            </div>
          </div>
        </div>
        <div class="xiamian">
          <div class="row row-bottom">
            <div class="block block-batch">
              <div class="block-title batch-title">{{ currentGroupName || '未选择群组' }}</div>
              <div class="batch-content">
                <div class="batch-panel">
                  <el-button type="success" size="mini" class="mb8" @click="handleBatchOpen">批量开仓</el-button>
                  <div class="mb8">
                    <el-radio-group v-model="batchOpenType">
                      <el-radio label="卖一" size="mini">卖一</el-radio>
                      <el-radio label="卖二" size="mini">卖二</el-radio>
                      <el-radio label="市价" size="mini">市价</el-radio>
                      <el-radio label="买一" size="mini">买一</el-radio>
                      <el-radio label="买二" size="mini">买二</el-radio>
                    </el-radio-group>
                  </div>
                  <div class="mb8">开仓比例：<el-input v-model="batchOpenRatio" size="mini" style="width:100px;"
                      placeholder="输入1~100" />%</div>
                  <div style="color:#888; font-size:13px; margin-bottom:8px;">
                    可用资金比例
                  </div>
                  <el-button type="danger" size="mini" class="mb8" @click="handleBatchClose">批量平仓</el-button>
                  <div class="mb8">
                    价格：
                    <el-radio-group v-model="batchCloseType">
                      <el-radio label="卖一" size="mini">卖一</el-radio>
                      <el-radio label="卖二" size="mini">卖二</el-radio>
                      <el-radio label="市价" size="mini">市价</el-radio>
                      <el-radio label="买一" size="mini">买一</el-radio>
                      <el-radio label="买二" size="mini">买二</el-radio>
                    </el-radio-group>
                  </div>
                  <div class="mb8">
                    类型：
                    <el-radio-group v-model="batchCloseMode" size="mini" style="margin-bottom:8px;">
                      <el-radio label="百分比">百分比</el-radio>
                      <el-radio label="列表">列表</el-radio>
                      <el-radio label="清仓">清仓</el-radio>
                    </el-radio-group>
                    <div v-if="batchCloseMode === '百分比'" style="color:#888; font-size:13px; margin-bottom:8px;">
                      平仓百分比：每个标的将按照指定百分比进行减仓
                    </div>
                    <div v-if="batchCloseMode === '列表'" style="color:#888; font-size:13px; margin-bottom:8px;">
                      列表：将标的列表全部按100%进行平仓
                    </div>
                    <div v-if="batchCloseMode === '清仓'" style="color:#888; font-size:13px; margin-bottom:8px;">
                      清仓：当前群组所有账号的全部持仓都会被全部卖出，请谨慎操作
                    </div>
                  </div>
                  <div v-if="batchCloseMode === '百分比'" class="mb8">
                    平仓比例：
                    <el-input v-model="batchCloseRatio" size="mini" style="width:100px;" placeholder="输入1~100">
                    </el-input>
                    %
                  </div>
                  <el-button type="warning" size="mini" @click="handleBatchCancel">批量撤单</el-button>
                </div>
              </div>
            </div>
            <div class="block block-account-list">
              <div class="block-title batch-title">
                账号列表
                <el-button type="primary" icon="el-icon-plus" size="mini" @click="showAddGroupUserDialog = true" circle
                  style="float:right;" />
              </div>
              <ul class="account-list-ul">
                <li v-for="item in accountList" :key="item.value">
                  {{ item.tdAcc }}
                  <el-button type="text" icon="el-icon-delete" size="mini" @click.stop.prevent="deleteGroupUser(item.id)"
                    style="color:#f56c6c; margin-left:4px;" v-if="groupList.length > 0" />
                </li>
              </ul>
            </div>
            <div class="block block-symbol-list">
              <div class="block-title batch-title">
                标的列表
                <!-- <el-button type="primary" icon="el-icon-plus" size="mini" circle style="float:right;" /> -->
              </div>
              <ul class="symbol-list-ul">
                <li v-for="(item, idx) in symbolList" :key="idx" class="symbol-list-item">
                  <span>
                    {{ item.name }}
                    <span style="margin-left:20px;">{{ item.price }}</span>
                    <span style="margin-left:20px;">{{ item.count }}</span>
                    <span style="color:#ff4d4f; margin-left:20px;">{{ item.ratio }}%</span>
                  </span>
                  <el-button type="text" icon="el-icon-delete" @click="symbolList.splice(idx, 1)"
                    class="symbol-list-delete-btn" />
                </li>
              </ul>
              <div style="margin:8px 0;color:#888;">
                当前总比例：{{ totalRatio }}%
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 账号信息，最右侧，独立一栏 -->
      <div class="block-accounts">
        <div class="account-vertical-slider">
          <div v-for="acc in accountInfo" :key="acc.td_acc" class="account-card"
            :class="{ selected: selectedAccountId === acc.td_acc }" @click="selectedAccountId = acc.td_acc">
            <div class="account-header">
              <span style="font-weight:bold;">{{ acc.td_acc }} {{ acc.name }}</span>
            </div>
            <div class="account-body">
              <div>
                <span>总资产</span> {{ acc.cash }}
                <span class="ml8">可用资金</span> {{ acc.cash }}
                <!-- <span class="ml8">锁定资金</span> {{ acc.locked }} -->
              </div>
              <div>
                <span>总市值</span> {{ acc.z_sz }}
                <span class="ml8">浮动盈亏</span> {{ acc.fd_yk }}
                <!-- <span class="ml8">持仓比例</span> {{ acc.positionRatio }} -->
              </div>
            </div>
          </div>
        </div>
        <!-- 当前选中账号的持仓和委托订单，折叠面板可开关 -->
        <div class="account-detail-section" v-if="selectedAccount">
          <el-collapse v-model="activeSections" accordion>
            <el-collapse-item name="p_list">
              <template #title>
                <span>持仓</span>
              </template>
              <el-table :data="selectedAccount.p_list" size="mini" border empty-text="暂无持仓" style="margin-bottom:12px;"
                height="300px">
                <el-table-column label="代码/名称" width="100">
                  <template slot-scope="scope">
                    <div>
                      <div>{{ scope.row.symbol }}</div>
                      <div style="color: #909399; font-size: 12px;">{{ scope.row.sec_name }}</div>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="持仓量/可用" width="100">
                  <template slot-scope="scope">
                    <div>
                      <div>{{ scope.row.kyCw }}</div>
                      <div style="color: #909399; font-size: 12px;">{{ scope.row.ky_cw }}</div>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="价格/成本" width="100">
                  <template slot-scope="scope">
                    <div>
                      <div>{{ scope.row.price }}</div>
                      <div style="color: #909399; font-size: 12px;">{{ scope.row.cbJj }}</div>
                    </div>
                  </template>
                </el-table-column>
              </el-table>
            </el-collapse-item>
            <!-- 委托订单 -->
            <el-collapse-item name="mlTradeEntrustOrderList">
              <template #title>
                <span>委托订单</span>
              </template>
              <el-table :data="selectedAccount.mlTradeEntrustOrderList" size="mini" border empty-text="暂无委托"
                height="300px">
                <el-table-column label="名字/代码" width="80">
                  <template slot-scope="scope">
                    <div>
                      <div>{{ scope.row.secName }}</div>
                      <div style="color: #909399; font-size: 12px;">{{ scope.row.symbol }}</div>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="数量/成交" width="80">
                  <template slot-scope="scope">
                    <div>
                      <div>{{ scope.row.wtSl }}</div>
                      <div style="color: #909399; font-size: 12px;">{{ scope.row.wtSl }}</div>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="买卖/状态" width="80">
                  <template slot-scope="scope">
                    <div>
                      <div>{{ scope.row.wtFx === 0 || scope.row.wtFx === '0' ? '买入' : '卖出' }}</div>
                      <div style="color: #909399; font-size: 12px;">{{ wtZtDict[scope.row.wtFx] || scope.row.wtFx }}</div>
                    </div>
                  </template>
                </el-table-column>
                <el-table-column label="价格/时间" width="80">
                  <template slot-scope="scope">
                    <div>
                      <div>{{ scope.row.wtJg }}</div>
                      <div style="color: #909399; font-size: 12px;">{{ scope.row.createTime ? scope.row.createTime.split('
                                              ')[0] : '' }}</div>
                    </div>
                  </template>
                </el-table-column>
              </el-table>
            </el-collapse-item>
          </el-collapse>
        </div>
      </div>
      <!-- 账号信息结束 -->
    </div>
    <!-- 弹窗等 -->
    <el-dialog title="股票搜索" :visible.sync="stockDialogVisible" width="420px" :modal-append-to-body="false"
      @close="stockSearchText = ''; stockSearchResults = [];">
      <div style="display:flex;align-items:center;gap:12px;">
        <el-input v-model="stockSearchText" placeholder="名称/代码/简称" size="small" style="flex:1"
          @keyup.enter.native="onStockSearch" />
        <el-button type="warning" size="small" @click="onStockSearch">查询</el-button>
      </div>
      <el-table :data="stockSearchResults" height="400" style="margin-top:16px;" size="small" @row-click="onSelectStock"
        highlight-current-row>
        <el-table-column prop="f14" label="名称" width="90" />
        <el-table-column prop="f12" label="代码" width="80" />
        <el-table-column prop="f2" label="当前价格" width="80" />
        <el-table-column prop="f3" label="涨跌幅" width="60" />
      </el-table>
    </el-dialog>
    <!-- 群组弹窗等 -->
    <el-dialog title="添加交易群组" :visible.sync="showAddGroupDialog" width="350px" @close="form.groupName = ''">
      <el-form :model="form" label-width="70px">
        <el-form-item label="群组名称">
          <el-input v-model="form.groupName" placeholder="请输入群组名称" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showAddGroupDialog = false">取 消</el-button>
        <el-button type="primary" :disabled="!form.groupName.trim()" @click="addGroups">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 群组组员弹窗等 -->
    <el-dialog title="添加组员" :visible.sync="showAddGroupUserDialog" width="350px" @close="user.tdAcc = ''">
      <el-form :model="form" label-width="70px">
        <el-form-item label="组员账号">
          <!-- <el-input v-model="user.tdAcc" placeholder="请输入用户账号" /> -->
          <el-select v-model="user.tdAcc" filterable placeholder="请输入搜索或选择用户">
            <el-option v-for="user in userList" :key="user.tdAcc" :label="user.tdAcc" :value="user.tdAcc" />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showAddGroupUserDialog = false">取 消</el-button>
        <el-button type="primary" :disabled="!user.tdAcc.trim()" @click="addGroupUser">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons')
import { getSymbolInfo, getMinuteData } from "@/api/business/documentation";
import { listGroupList, delGroup, listUserAll, addGroup, listGroupUser, addGroupUserData, financialInformation, batchBuy, batchOpeningData, batchSellSymbolData, batchCancelOrder } from "@/api/business/group";

export default {
  name: "TradePage",
  data() {
    return {
      direction: "",
      batchOpenRatio: "",
      groupId: this.mainId,             // 群组id
      users: this.accountList,          // 群组成员列表
      symbols: this.symbolList,        // 标的列表
      symbolList: [],
      currentGroupName: '',
      wtZtDict: {
        '0': '报单申请',
        '1': '报单成功',
        '2': '部分成交',
        '3': '全部成交',
        '4': '撤单申请',
        '5': '撤单成功',
        '6': '订单异常',
      },
      showAddGroupDialog: false,
      showAddGroupUserDialog: false,
      groupList: [
      ],
      form: {
        groupName: ""
      },
      user: {
        tdAcc: ""
      },
      activeGroup: "",
      stockDialogVisible: false,
      stockSearchText: '',
      stockSearchResults: [],
      allStockList: [],
      stockQuery: "",
      price: "0",
      count: "",
      ratio: "",
      downLimit: "0",
      upLimit: "0",
      name: "601398",
      symbol: "工商银行",
      userList: [],
      sellList: [
        { value: "卖五", askprice: "7.57", askvolume: "11073" },
        { value: "卖四", askprice: "7.56", askvolume: "27978" },
        { value: "卖三", askprice: "7.55", askvolume: "15151" },
        { value: "卖二", askprice: "7.54", askvolume: "21026" },
        { value: "卖一", askprice: "7.53", askvolume: "7988" }
      ],
      buyList: [
        { value: "买一", bidprice: "7.52", bidvolume: "3340" },
        { value: "买二", bidprice: "7.51", bidvolume: "3634" },
        { value: "买三", bidprice: "7.50", bidvolume: "9066" },
        { value: "买四", bidprice: "7.49", bidvolume: "9075" },
        { value: "买五", bidprice: "7.48", bidvolume: "5647" }
      ],
      selectedAccountId: "",
      activeSections: ["p_list"],
      accountInfo: [
        {
          td_acc: '89064533',
          name: '张三丰',
          cash: '10,043,881.53',
          cash: '9,272,074.53',
          locked: '0.00',
          z_sz: '771,807.00',
          fd_yk: '-20,795.11',
          // positionRatio: '7.68%',
          p_list: [
            { symbol: '600001', name: '浦发银行', amount: 10000, cash: 8000, cost: 7.52, z_sz: 75200, fd_yk: 1200 },
            { symbol: '600002', name: '平安银行', amount: 5000, cash: 5000, cost: 12.35, z_sz: 61750, fd_yk: -500 }
          ],
          mlTradeEntrustOrderList: [
            { orderId: 'A123', symbol: '600001', name: '浦发银行', type: '买入', price: 7.55, amount: 1000, status: '已报', time: '09:35:20' },
            { orderId: 'A124', symbol: '600002', name: '平安银行', type: '卖出', price: 12.40, amount: 500, status: '部分成交', time: '09:40:15' }
          ]
        },
      ],
      accountList: [
      ],
      mainId: '',
      batchOpenType: '卖一',
      batchCloseType: '卖一',
      batchCloseRatio: "",
      chartInstance: null,
      batchCloseMode: '百分比'
    }
  },
  computed: {
    totalRatio() {
      return this.symbolList.reduce((sum, item) => sum + Number(item.ratio), 0);
    },
    selectedAccount() {
      return this.accountInfo.find(acc => acc.td_acc === this.selectedAccountId);
    }
  },
  created() {
    this.loadUserList();
  },
  watch: {
    batchCloseType: {
      handler() {
        this.replaceSymbolListPriceForClose();
      }
    },
    batchOpenType: {
      handler() {
        // 切换类型时自动替换symbolList里price
        this.replaceSymbolListPrice();
      }
    },
    batchCloseRatio: {
      handler(newVal) {
        this.replaceSymbolListRatioForClose(newVal);
      }
    },
    batchCloseMode(newVal) {
      if (newVal === "列表") {
        // 将 symbolList 里的每个标的比例设置为 100
        this.symbolList = this.symbolList.map(symbol => ({
          ...symbol,
          ratio: 100,
          closeRatio: 100
        }));
      }
    }
  },
  mounted() {
    this.fetchGroups();
    if (this.accountInfo.length) {
      this.selectedAccountId = this.accountInfo[0].td_acc;
    }
    this.mockTimeshareData(this.name, this.symbol);
    window.addEventListener("resize", this.resizeChart);
    this.fetchStockList()
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.resizeChart);
    if (this.chartInstance) this.chartInstance.dispose();
  },
  methods: {
    loadUserList() {
      listUserAll().then(res => {
        this.userList = res.data;
      });
    },
    async handleBatchCancel() {
      if (!this.mainId) {
        this.$message.warning('请先选择群组');
        return;
      }
      try {
        const res = await batchCancelOrder({ users: this.accountList });
        if (res.code == 200) {
          this.$message.success(res.msg);
        }
      } catch (e) {
        this.$message.error('批量撤单失败');
      }
    },
    replaceSymbolListRatioForClose(newRatio) {
      this.symbolList = this.symbolList.map(symbol => ({
        ...symbol,
        ratio: newRatio
      }));
    },
    getClosePriceByType(symbol) {
      switch (this.batchCloseType) {
        case "卖一":
          return symbol.sellPanKouVos[4]?.askprice || '';
        case "卖二":
          return symbol.sellPanKouVos[3]?.askprice || '';
        case "买一":
          return symbol.buyPanKouVos[0]?.bidprice || '';
        case "买二":
          return symbol.buyPanKouVos[1]?.bidprice || '';
        case "市价":
          // 假设市价买入用卖一
          return symbol.price || ''; // 现价
        default:
          return '';
      }
    },
    replaceSymbolListPriceForClose() {
      this.symbolList = this.symbolList.map(symbol => ({
        ...symbol,
        price: this.getClosePriceByType(symbol)
      }));
    },
    async handleBatchClose() {
      this.replaceSymbolListPriceForClose();
      if (!this.accountList.length) {
        this.$message.warning('该群组下没有组员');
        return;
      }
      if (!this.symbolList.length && this.batchCloseMode != "清仓") {
        this.$message.warning('请先添加标的');
        return;
      }
      if (
        (!this.batchCloseRatio ||
          isNaN(Number(this.batchCloseRatio)) ||
          Number(this.batchCloseRatio) <= 0 ||
          Number(this.batchCloseRatio) > 100) && this.batchCloseMode != "清仓"
      ) {
        this.$message.warning('请输入1~100的平仓比例');
        return;
      }
      if (this.batchCloseMode === "列表") {
        const symbolsWithPrice = this.symbolList.map(symbol => ({
          ...symbol,
          closePrice: this.getClosePriceByType(symbol),
          closeRatio: 100
        }));
        // 调用API
        const res = await batchSellSymbolData({
          users: this.accountList,
          symbols: symbolsWithPrice,
          entrustDirection: 1 // 卖出/平仓
        });
        if (res.code == 200) {
          this.$message.success(res.msg);
        }
        return;
      }
      if (this.batchCloseMode === "百分比") {
        const symbolsWithPrice = this.symbolList.map(symbol => {
          return {
            ...symbol,
            closePrice: this.getClosePriceByType(symbol),
            closeRatio: this.batchCloseRatio,
          }
        });
        try {
          // 假设API叫 batchSell，委托方向为1
          const res = await batchSellSymbolData({
            users: this.accountList,
            symbols: symbolsWithPrice,
            direction: 1, // 1=卖出/平仓
            batchCloseMode: this.batchCloseMode
          });
          if (res.code == 200) {
            this.$message.success(res.msg);
          }
        } catch (e) {
          this.$message.error('批量平仓失败');
        }
      }
      if (this.batchCloseMode === "清仓") {
        const symbolsWithPrice = this.symbolList.map(symbol => {
          return {
            ...symbol,
            closePrice: this.getClosePriceByType(symbol),
            closeRatio: this.batchCloseRatio,
          }
        });
        try {
          // 假设API叫 batchSell，委托方向为1
          const res = await batchSellSymbolData({
            users: this.accountList,
            // symbols: symbolsWithPrice,
            direction: 1, // 1=卖出/平仓
            batchCloseMode: this.batchCloseMode
          });
          if (res.code == 200) {
            this.$message.success(res.msg);
          }
        } catch (e) {
          this.$message.error('批量平仓失败');
        }
      }

    },
    // 获取每个标的的开仓价格
    getOpenPriceByType(symbol) {
      switch (this.batchOpenType) {
        case "卖一":
          return symbol.sellPanKouVos[4]?.askprice || '';
        case "卖二":
          return symbol.sellPanKouVos[3]?.askprice || '';
        case "买一":
          return symbol.buyPanKouVos[0]?.bidprice || '';
        case "买二":
          return symbol.buyPanKouVos[1]?.bidprice || '';
        case "市价":
          // 假设市价买入用卖一
          return symbol.price || ''; // 现价
        default:
          return '';
      }
    },
    replaceSymbolListPrice() {
      this.symbolList = this.symbolList.map(symbol => ({
        ...symbol,
        price: this.getOpenPriceByType(symbol)
      }));
    },
    // 批量开仓
    async handleBatchOpen() {
      if (!this.accountList.length) {
        this.$message.warning('该群组下没有组员');
        return;
      }
      if (!this.symbolList.length) {
        this.$message.warning('请先添加标的');
        return;
      }
      if (
        !this.batchOpenRatio ||
        isNaN(Number(this.batchOpenRatio)) ||
        Number(this.batchOpenRatio) <= 0 ||
        Number(this.batchOpenRatio) > 100
      ) {
        this.$message.warning('请输入1~100的开仓比例');
        return;
      }
      // 校验总比例不能超过100
      const totalRatio = this.symbolList.reduce((sum, item) => sum + Number(item.ratio), 0);
      if (totalRatio > 100) {
        this.$message.warning('所有标的比例之和不能超过100%');
        return;
      }
      // 组装symbols，自动带上对应的五档价
      const symbolsWithPrice = this.symbolList.map(symbol => {
        return {
          ...symbol,
          openPrice: this.getOpenPriceByType(symbol),
          openRatio: this.batchOpenRatio
        }
      });
      try {
        const res = await batchOpeningData({
          users: this.accountList,
          symbols: symbolsWithPrice,
          direction: 0 // 0=买入，1=卖出
        });
        if (res.code == 200) {
          this.$message.success(res.msg);
        }
      } catch (e) {
        this.$message.error('批量开仓失败');
      }
    },
    async handleBatchBuy() {
      const ratio = Number(this.ratio);
      if (!this.mainId) {
        this.$message.warning('请先选择群组');
        return;
      }
      if (!this.accountList.length) {
        this.$message.warning('该群组下没有组员');
        return;
      }
      if (!this.symbolList.length) {
        this.$message.warning('请先添加标的');
        return;
      }

      // 组装数据
      // groupId: this.mainId,
      this.users = this.accountList,
        this.symbols = this.symbolList
      this.direction = "0"
      // 校验总比例不能超过100
      const totalRatio = this.symbolList.reduce((sum, item) => sum + Number(item.ratio), 0);
      debugger
      if (totalRatio > 100) {
        this.$message.warning('所有标的比例之和不能超过100%');
        return;
      }
      // 调用后端接口（你自己实现的API）
      try {
        const res= await batchBuy({ users: this.users, symbols: this.symbols, direction: this.direction })
        if (res.code == 200) {
          this.$message.success(res.msg);
        }
      } catch (e) {
        this.$message.error('批量买入失败');
      }
    },
    async handleBatchSell() {
      if (!this.mainId) {
        this.$message.warning('请先选择群组');
        return;
      }
      if (!this.accountList.length) {
        this.$message.warning('该群组下没有组员');
        return;
      }
      if (!this.symbolList.length) {
        this.$message.warning('请先添加标的');
        return;
      }
      // 组装数据
      // groupId: this.mainId,
      this.users = this.accountList,
        this.symbols = this.symbolList
      this.direction = "1"
      // 调用后端接口（你自己实现的API）
      try {
        const res= await batchBuy({ users: this.users, symbols: this.symbols, direction: this.direction })
        debugger
        if (res.code == 200) {
          this.$message.success(res.msg);
        }
      } catch (e) {
        this.$message.error('批量买入失败');
      }
    },
    addSymbolToList() {
      const name = this.stockQuery.trim();
      const ratio = Number(this.ratio);
      const count = Number(this.count);
      if (!name) {
        this.$message.warning('请输入标的名称/代码');
        return;
      }
      if (!this.count || isNaN(count) || count <= 0) {
        this.$message.warning('请输入买入量/卖出量');
        return;
      }
      if (!this.ratio || isNaN(ratio) || ratio <= 0) {
        this.$message.warning('请输入有效的比例');
        return;
      }

      // 防止重复
      if (this.symbolList.some(item => item.name === name)) {
        this.$message.warning('该标的已在列表中，不能重复添加');
        return;
      }
      this.symbolList.push({
        name: name,
        price: this.price,
        ratio: ratio, // 加入比例
        count: count,
        downLimit: this.downLimit,//跌停
        upLimit: this.upLimit,
        buyPanKouVos: JSON.parse(JSON.stringify(this.buyList)),   // 深拷贝保存
        sellPanKouVos: JSON.parse(JSON.stringify(this.sellList)), // 深拷贝保存
      });
    },
    async getAccountData(accountList) {
      const tdAccs = accountList.map(item => item.tdAcc)
      if (tdAccs.length === 0) {
        this.$modal.msgError("群组下没成员请添加");
        return
      }
      const res = await financialInformation({ tdAccs: tdAccs.join(',') });
      this.accountInfo = res.data
      const accSet = new Set(this.accountInfo.map(item => item.td_acc));
      debugger
      console.log(this.userList)
      this.userList = this.userList.filter(user => !accSet.has(user.tdAcc));
    },
    async addGroupUser() {
      const tdAcc = this.user.tdAcc.trim();
      if (!tdAcc) return;
      let mainId = this.mainId
      addGroupUserData({ tdAcc: tdAcc, mainId: mainId })
      // 调后端API新增
      this.user.tdAcc = '';
      this.showAddGroupUserDialog = false;
      await this.handleGroupSelect(this.mainId); // 重新拉取群组
    },
    async handleGroupSelect(id) {
      this.activeGroup = id;
      this.mainId = id
      // 查找群组名
      const grp = this.groupList.find(g => g.id == id);
      this.currentGroupName = grp ? grp.name : '';
      const res = await listGroupUser({ id })
      this.accountList = res.data
      this.getAccountData(this.accountList)
    },
    deleteGroupUser(idx) {
      const ids = idx
      this.$modal.confirm('是否确认删除组员').then(function () {
        return delGroup(ids);
      }).then(() => {
        this.handleGroupSelect(this.mainId)
        this.$modal.msgSuccess("删除成功");
      }).catch(() => { });
    },
    deleteGroup(idx) {
      const ids = idx
      this.$modal.confirm('是否确认删除交易组').then(function () {
        return delGroup(ids);
      }).then(() => {
        this.fetchGroups()
        this.$modal.msgSuccess("删除成功");
      }).catch(() => { });
    },
    async fetchGroups() {
      const res = await listGroupList()
      this.groupList = res.data; // 假设返回是 ["群组A", "群组B", ...]
      if (this.groupList.length && !this.activeGroup) {
        this.activeGroup = this.groupList[0];
      }
    },
    // 添加群组
    async addGroups() {
      const name = this.form.groupName.trim();
      if (!name) return;
      addGroup({ name })
      // 调后端API新增
      this.form.groupName = '';
      this.showAddGroupDialog = false;
      await this.fetchGroups(); // 重新拉取群组
      this.activeGroup = name;
    },
    async mockTimeshareData(f12, f14) {
      const response = await getMinuteData({ f12, f14 })
      if (response.code === 200 && Array.isArray(response.data.data)) {
        this.drawChart(response.data.data)
      } else {
        this.$modal.msgError("数据获取失败")
      }
    },
    drawChart(raw) {
      const times = raw.map(i => i[1].slice(11, 16));
      const prices = raw.map(i => i[3]);
      const vols = raw.map(i => i[6]);
      const barColors = raw.map((d, idx) => {
        if (idx === 0) return "#ef232a";
        return d[3] >= raw[idx - 1][3] ? "#ef232a" : "#14b143";
      });

      if (this.chartInstance) this.chartInstance.dispose();
      this.chartInstance = echarts.init(this.$refs.timeshareChart);

      const option = {
        animation: false,
        tooltip: { trigger: "axis" },
        axisPointer: { type: "cross", link: [{ xAxisIndex: 'all' }] },
        grid: [
          { left: 6, right: 6, top: 8, height: "60%" },
          { left: 6, right: 6, top: "68%", height: "26%" }
        ],
        xAxis: [
          {
            type: "category",
            data: times,
            boundaryGap: false,
            axisLine: { lineStyle: { color: "#ccc" } },
            axisTick: { show: false },
            axisLabel: { color: "#888" },
            splitLine: { show: false },
            min: "dataMin",
            max: "dataMax"
          },
          {
            type: "category",
            gridIndex: 1,
            data: times,
            boundaryGap: false,
            axisLine: { lineStyle: { color: "#ccc" } },
            axisTick: { show: false },
            axisLabel: {
              color: "#888",
              formatter: (v, idx) => idx === 0 ? "09:30" : (idx === times.length - 1 ? "15:00" : "")
            },
            splitLine: { show: false },
            min: "dataMin",
            max: "dataMax"
          }
        ],
        yAxis: [
          {
            scale: true,
            position: "right",
            axisLabel: { color: "#888" },
            axisLine: { show: false },
            axisTick: { show: false },
            splitLine: { show: false }
          },
          {
            scale: true,
            gridIndex: 1,
            position: "right",
            axisLabel: { color: "#888" },
            axisLine: { show: false },
            axisTick: { show: false },
            splitLine: { show: false }
          }
        ],
        series: [
          {
            name: "分时价",
            type: "line",
            data: prices,
            symbol: "none",
            lineStyle: { color: "#2076e7", width: 1.5 },
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                { offset: 0, color: "#2076e7cc" },
                { offset: 1, color: "#ffffff00" }
              ])
            },
            xAxisIndex: 0,
            yAxisIndex: 0,
            z: 2
          },
          {
            name: "成交量",
            type: "bar",
            data: vols,
            xAxisIndex: 1,
            yAxisIndex: 1,
            barWidth: 5,
            itemStyle: {
              color: (params) => barColors[params.dataIndex]
            },
            z: 1
          }
        ]
      };

      this.chartInstance.setOption(option);
    },
    resizeChart() {
      if (this.chartInstance) this.chartInstance.resize();
    },
    async fetchStockList() {
      try {
        this.allStockList = JSON.parse(localStorage.getItem('symbolInfoCache'))
      } catch (e) {
        this.$message.error('股票列表获取失败')
      }
    },
    pricePlus() {
      this.price = (parseFloat(this.price) + 0.01).toFixed(2);
    },
    priceMinus() {
      this.price = (parseFloat(this.price) - 0.01).toFixed(2);
    },
    countPlus() {
      this.count = parseInt(this.count || 0) + 100;
    },
    countMinus() {
      this.count = Math.max(0, parseInt(this.count || 0) - 100);
    },
    onStockSearch() {
      const query = this.stockSearchText.trim();
      if (!query) {
        this.stockSearchResults = this.allStockList;
        return;
      }
      this.stockSearchResults = this.allStockList.filter(item =>
        item.f14.includes(query) ||
        item.f12.includes(query)
      );
    },
    onSelectStock(row) {
      this.stockQuery = row.f14 + ' ' + row.f12;
      this.name = row.f14,
        this.symbol = row.f12
      getSymbolInfo({ f12: row.f12, f14: row.f14 }).then(res => {
        this.price = res.data[0].f2
        this.upLimit = res.data[0].upper_limit
        this.downLimit = res.data[0].lower_limit
        this.sellList = res.data[0].sellPanKouVos.reverse()
        this.buyList = res.data[0].buyPanKouVos
      })
      this.mockTimeshareData(this.symbol, this.name)
      this.stockDialogVisible = false;
    },
  }
}
</script>

<style scoped>
.trade-page {
  font-family: "Microsoft YaHei", Arial, sans-serif;
  background: #f4f6fa;
  min-height: 100vh;
}

.main-area {
  display: flex;
  flex-direction: row;
  height: calc(100vh - 42px);
  overflow: hidden;
  width: 1400px;
}

.main-content {
  flex: 1 1 0;
  min-width: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.block-accounts {
  width: 320px;
  min-width: 260px;
  max-width: 400px;
  background: #fff;
  border-left: 1px solid #e5e5e5;
  height: 100vh;
  position: sticky;
  top: 0;
  right: 0;
  z-index: 10;
  box-shadow: -1px 0 5px #0001;
  display: flex;
  flex-direction: column;
  padding: 16px 6px 0 6px;
  overflow-y: auto;
}

.account-vertical-slider {
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  gap: 8px;
  height: 380px;
  scrollbar-width: thin;
  margin-bottom: 12px;
}

.account-card {
  height: 300px;
  background: #fff3e0;
  border-radius: 4px;
  box-shadow: 0 1px 2px #0001;
  cursor: pointer;
  border: 2px solid transparent;
  transition: border 0.2s;
  margin-bottom: 4px;
}

.account-card.selected {
  border-color: #189ad6;
}

.account-header {
  color: #d2691e;
  margin-bottom: 2px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.account-body>div {
  margin-bottom: 2px;
  font-size: 14px;
}

.ml8 {
  margin-left: 8px;
}

.account-detail-section {
  margin-top: 10px;
}

.entrust-depth-card {
  width: 100%;
}

.entrust-two-cols {
  display: flex;
  flex-direction: row;
  width: 100%;
}

.entrust-form {
  max-width: 260px;
  padding-left: 18px;
  /* 左侧留间隔，不贴边 */
  padding-top: 10px;
  display: flex;
  flex-direction: column;
}

.entrust-form-item {
  width: 200px !important;
  min-width: 200px !important;
  max-width: 200px !important;
  margin-bottom: 16px !important;
  /* 上下间隔一致 */
}

.entrust-flex-row {
  display: flex;
  align-items: center;
  width: 200px;
  min-width: 200px;
  max-width: 200px;
  margin-bottom: 16px;
}

.entrust-flex-row .el-input {
  flex: 1 1 0;
  min-width: 0;
  max-width: none;
}

.entrust-flex-row .el-button {
  flex-shrink: 0;
}

.depth-side {
  max-width: 180px;
  margin-left: 20px;
  /* padding-left: 40px; */
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.depth-table {
  font-size: 13px;
}

.depth-row {
  display: flex;
  justify-content: space-between;
  line-height: 1.7;
  margin-bottom: 2px;
}

.sell-row .depth-type {
  color: #fa541c;
  width: 34px;
}

.buy-row .depth-type {
  color: #28b76b;
  width: 34px;
}

.depth-price {
  min-width: 36px;
  text-align: right;
}

.depth-volume {
  min-width: 44px;
  text-align: right;
}

.entrust-btns-bottom-vertical {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  margin-top: 12px;
  padding-left: 10px;
  width: 100%;
  gap: 8px;
}

.entrust-buy,
.entrust-sell {
  width: 95% !important;
  box-sizing: border-box;
  padding-left: 10px;
  margin: 0 !important;
  border-radius: 4px;
  font-size: 15px;
}

.entrust-ratio-add-group {
  display: flex;
  width: 100%;
  gap: 8px;
  padding-right: 23px;
}

.entrust-ratio-input {
  flex: 1 1 0;
  min-width: 0;
  border-radius: 4px 0 0 4px;
  /* 确保与按钮无间隙，左侧圆角 */
}

.entrust-add-btn {
  flex: 1 1 0;
  min-width: 0;
  max-width: none;
  background: #ffc107;
  color: #fff;
  border: 1px solid #ffc107;
  font-weight: bold;
  font-size: 15px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  /* 关键：让文字水平居中 */
  border-radius: 4px;
}

.header-title {
  letter-spacing: 1px;
}

.row {
  display: flex;
  width: 100%;
  margin-bottom: 6px;
}

.row-top .block {
  padding-left: 10px;
  margin-right: 6px;
}

.row-bottom .block {
  padding-left: 10px;
  margin-right: 6px;
}

.row-top .block:last-child,
.row-bottom .block:last-child {
  margin-right: 0;
}

.block {
  background: #fff;
  border: 1px solid #bdbdbd;
  border-radius: 3px;
  box-shadow: 0 1px 4px #00000009;
  display: flex;
  flex-direction: column;
}

.block-chart {
  width: 480px;
  /* margin-bottom: 24px; */
}

.block-entrust {
  width: 34%;
  min-width: 200px;
  max-width: 400px;
  align-items: center;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
}

.block-group {
  width: 20%;
  min-width: 200px;
  max-width: 300px;
}


.block-batch {
  width: 40%;
  min-width: 340px;
  max-width: 440px;
}

.block-account-list {
  width: 30%;
  min-width: 195px;
  max-width: 300px;
}

.block-symbol-list {
  width: 35%;
  min-width: 195px;
  max-width: 400px;
}

.block-title {
  font-weight: bold;
  background: #888;
  color: #fff;
  padding: 5px 12px;
  font-size: 15px;
  border-radius: 2px 2px 0 0;
}

.group-title {
  background: #115b9c;
}

.batch-title {
  background: #888;
}

.chart-area {
  background: #fafbfc;
  border: 1px solid #e5e5e5;
  height: 480px;
  /* <<< 这里改大 */
  margin: 12px 8px 8px 8px;
  border-radius: 3px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.chart-placeholder {
  height: 100%;
  width: 100%;
  min-width: 120px;
}

.chart-footer {
  font-size: 12px;
  color: #888;
  margin: 0 8px 2px 8px;
}

.flex-row {
  display: flex;
  align-items: center;
}

.account-list-ul,
.symbol-list-ul {
  margin: 8px 0 0 0;
  padding: 0 0 0 18px;
  font-size: 15px;
  list-style: none;
}

.account-list-ul li {
  margin-bottom: 6px;
  color: #222;
}

.symbol-list-ul li {
  margin-bottom: 4px;
}

.batch-panel {
  padding: 10px 0 0 10px;
}

.mb8 {
  margin-bottom: 8px;
}

.limit-price {
  font-size: 13px;
}

.el-dialog__body {
  padding-top: 10px !important;
}

.el-table__row {
  cursor: pointer;
}

.depth-middle-line {
  height: 1px;
  background: #ddd;
  margin: 4px 0;
  border: none;
  width: 100%;
}

.ml8 {
  margin-left: 8px;
}

.xiamian {
  width: 100%;
  border: 1px solid #0c0000;
}

.shangmian {
  width: 100%;
  border: 1px solid #0c0000;
}

.symbol-list-ul .symbol-list-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* 内容和按钮分两端 */
  margin-bottom: 4px;
  padding-right: 0;
  /* 可根据需求调整 */
}

.symbol-list-delete-btn {
  margin-left: 10px;
  /* 可根据需求调整大小等样式 */
}
</style>